﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Module.MultiSiteFields.Interfaces;
using Core.Module.Interfaces.Model;
using umbraco.cms.presentation.Trees;

namespace Module.MultiSiteFields.Controllers
{
    public class TreeSettingsController : IStartPointsController
    {
        private Dictionary<TreeDefinition, List<TreeStartPoint>> StartPoints;
        public TreeSettingsController()
        {
            StartPoints = TreeDefinitionCollection.Instance.ToDictionary(v => v, v => new List<TreeStartPoint>());
        }

        public Dictionary<TreeDefinition, List<TreeStartPoint>> GetAll()
        {
            return StartPoints;
        }
        public List<TreeStartPoint> GetAll(string forTreeWithAlias)
        {
            return EnsureTreePoints(forTreeWithAlias);
        }

        private List<TreeStartPoint> EnsureTreePoints(string treeAlais)
        {
            List<TreeStartPoint> points = StartPoints.Where(t => t.Key.Tree.Alias.Equals(treeAlais)).Select(ti => ti.Value).FirstOrDefault();
            if (points == null) throw new ArgumentOutOfRangeException("no one tree definition been found with alias:" + treeAlais + ".Can't register tree start point!StartPointsController.RegisterStartPoint");
            return points;
        }

        public TreeStartPoint Register(string treeAlais, string pointAlias, ActionWithResult<bool,TreeStartPoint, IModuleNode> methodToExact)
        {
            List<TreeStartPoint> points =EnsureTreePoints(treeAlais);
            TreeStartPoint result = null;// points.Where(pi => pi.Alias.Equals(pointAlias)).FirstOrDefault();
            //if (result == null)
            //{
                result = new TreeStartPoint() { TreeAlias = treeAlais, Alias = pointAlias};
                points.Add(result);
            //}
            result.GetSettings = methodToExact;
            return result;
        }
        public TreeStartPoint ResolveSettings(TreeStartPoint treeStartPointItem, IModuleNode node)
        {
            List<TreeStartPoint> points = EnsureTreePoints(treeStartPointItem.TreeAlias);
            foreach (TreeStartPoint pitem in points.Where(spi => spi.Alias.Equals(treeStartPointItem.Alias)))
            {
                if (pitem.GetSettings(treeStartPointItem, node)) return treeStartPointItem;
            }
            return treeStartPointItem;
        }

        public KeyValuePair<string, string> SetValue(TreeStartPoint treeStartPoint, string settingsKey, string settingsValue)
        {
            List<KeyValuePair<string, string>> srcSettings = treeStartPoint.Settings.ToList();
            srcSettings.RemoveAll(sp => sp.Key != null && sp.Key.Equals(settingsKey));
            KeyValuePair<string, string> rSetting= new KeyValuePair<string, string>(settingsKey, settingsValue);
            srcSettings.Add(rSetting);
            treeStartPoint.Settings = srcSettings.ToArray();
            return rSetting;
        }
    }

    
    public class TreeStartPoint 
    {
        public TreeStartPoint(){}

        public string Alias { get; set; }
        public string TreeAlias { get; set; }
       
        public ActionWithResult<bool, TreeStartPoint, IModuleNode> GetSettings { get; set; }


        public KeyValuePair<string, string>[] Settings { get; set; }
    }
}
